import St from 'gi://St';
import * as GnomeSession from '../../misc/gnomeSession.js';
-import * as Main from '../main.js';
import * as MessageTray from '../messageTray.js';
Gio._promisify(Gio.Mount.prototype, 'guess_content_type');
class AutorunDispatcher {
constructor(manager) {
this._manager = manager;
- this._sources = [];
+ this._notifications = new Map();
this._settings = new Gio.Settings({schema_id: SETTINGS_SCHEMA});
}
return AutorunSetting.ASK;
}
- _getSourceForMount(mount) {
- let filtered = this._sources.filter(source => source.mount === mount);
-
- // we always make sure not to add two sources for the same
- // mount in addMount(), so it's safe to assume filtered.length
- // is always either 1 or 0.
- if (filtered.length === 1)
- return filtered[0];
-
- return null;
- }
-
- _addSource(mount, apps) {
- // if we already have a source showing for this
- // mount, return
- if (this._getSourceForMount(mount))
+ _addNotification(mount, apps) {
+ // Only show a new notification if there isn't already an existing one
+ if (this._notifications.has(mount))
return;
- // add a new source
- this._sources.push(new AutorunSource(this._manager, mount, apps));
+ const source = MessageTray.getSystemSource();
+ const notification = new AutorunNotification(source, mount, apps);
+ notification.connect('destroy', () => this._notifications.delete(mount));
+ this._notifications.set(mount, notification);
+ source.showNotification(notification);
}
addMount(mount, apps, contentTypes) {
// we fallback here also in case the settings did not specify 'ask',
// but we failed launching the default app or the default file manager
if (!success)
- this._addSource(mount, apps);
+ this._addNotification(mount, apps);
}
removeMount(mount) {
- let source = this._getSourceForMount(mount);
-
- // if we aren't tracking this mount, don't do anything
- if (!source)
- return;
-
- // destroy the notification source
- source.destroy();
+ this._notifications.get(mount)?.destroy();
}
}
-const AutorunSource = GObject.registerClass(
-class AutorunSource extends MessageTray.Source {
- constructor(manager, mount, apps) {
- super({
- title: mount.get_name(),
- icon: mount.get_icon(),
- });
-
- this._manager = manager;
- this.mount = mount;
- this.apps = apps;
-
- this._notification = new AutorunNotification(this._manager, this);
-
- // add ourselves as a source, and popup the notification
- Main.messageTray.add(this);
- this.showNotification(this._notification);
- }
-
- _createPolicy() {
- return new MessageTray.NotificationApplicationPolicy('org.gnome.Nautilus');
- }
-});
-
const AutorunNotification = GObject.registerClass(
class AutorunNotification extends MessageTray.Notification {
- _init(manager, source) {
- super._init(source, source.title);
+ constructor(source, mount, apps) {
+ super(source, mount.get_name());
- this._manager = manager;
- this._mount = source.mount;
+ this.gicon = mount.get_icon();
+
+ this._mount = mount;
+ this._apps = apps;
}
createBanner() {
let banner = new MessageTray.NotificationBanner(this);
- this.source.apps.forEach(app => {
+ this._apps.forEach(app => {
let actor = this._buttonForApp(app);
if (actor)
import * as Signals from '../../misc/signals.js';
import * as Dialog from '../dialog.js';
-import * as Main from '../main.js';
import * as MessageTray from '../messageTray.js';
import * as ModalDialog from '../modalDialog.js';
import * as ShellEntry from '../shellEntry.js';
}
_showNotification(requestId, connection, settingName, hints, flags) {
- const source = new MessageTray.Source({
- title: _('Network Manager'),
- iconName: 'network-transmit-receive',
- });
- source.policy = new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
-
let title, body;
let connectionSetting = connection.get_setting_connection();
return;
}
- let notification = new MessageTray.Notification(source, title, body);
+ const source = new MessageTray.getSystemSource();
+ const notification = new MessageTray.Notification(source, title, body);
+ notification.iconName = 'dialog-password-symbolic';
notification.connect('activated', () => {
notification.answered = true;
delete this._notifications[requestId];
});
- Main.messageTray.add(source);
source.showNotification(notification);
}
if (lookingGlass?.isOpen)
return; // assume user action
- const source = new MessageTray.SystemNotificationSource();
- messageTray.add(source);
+ const source = MessageTray.getSystemSource();
const notification = new MessageTray.Notification(source,
_('System was put in unsafe mode'),
_('Apps now have unrestricted access'));
* @param {string} details Additional information
*/
export function notify(msg, details) {
- let source = new MessageTray.SystemNotificationSource();
- messageTray.add(source);
+ const source = MessageTray.getSystemSource();
let notification = new MessageTray.Notification(source, msg, details);
notification.setTransient(true);
source.showNotification(notification);
return systemNotificationSource;
}
-
-export const SystemNotificationSource = GObject.registerClass(
-class SystemNotificationSource extends Source {
- constructor() {
- super({
- title: _('System Information'),
- iconName: 'dialog-information-symbolic',
- });
- }
-
- open() {
- this.destroy();
- }
-});
const OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
class ShellInfo {
- constructor() {
- this._source = null;
- }
-
setMessage(text, options) {
options = Params.parse(options, {
undoCallback: null,
forFeedback: false,
});
+ const source = MessageTray.getSystemSource();
let undoCallback = options.undoCallback;
let forFeedback = options.forFeedback;
- if (this._source == null) {
- this._source = new MessageTray.SystemNotificationSource();
- this._source.connect('destroy', () => {
- this._source = null;
- });
- Main.messageTray.add(this._source);
- }
-
- let notification = null;
- if (this._source.notifications.length === 0) {
- notification = new MessageTray.Notification(this._source, text, null);
- notification.setTransient(true);
- notification.setForFeedback(forFeedback);
+ if (!this._notification) {
+ this._notification = new MessageTray.Notification(source, text, null);
+ this._notification.setTransient(true);
+ this._notification.setForFeedback(forFeedback);
+ this._notification.connect('destroy', () => delete this._notification);
} else {
- notification = this._source.notifications[0];
- notification.update(text, null, {clear: true});
+ this._notification.update(text, null, {clear: true});
}
if (undoCallback)
- notification.addAction(_('Undo'), () => undoCallback());
+ this._notification.addAction(_('Undo'), () => undoCallback());
- this._source.showNotification(notification);
+ source.showNotification(this._notification);
}
}
import * as Animation from './animation.js';
import * as CheckBox from './checkBox.js';
import * as Dialog from './dialog.js';
-import * as Main from './main.js';
import * as MessageTray from './messageTray.js';
import * as ModalDialog from './modalDialog.js';
import * as Params from '../misc/params.js';
}
_onShowUnmountProgress(op, message, timeLeft, bytesLeft) {
- if (!this._notifier)
- this._notifier = new ShellUnmountNotifier();
-
if (bytesLeft === 0)
- this._notifier.done(message);
+ this._showUnmountNotificationDone(message);
else
- this._notifier.show(message);
+ this._showUnmountNotification(message);
}
borrowDialog() {
this._dialog?.disconnectObject(this);
return this._dialog;
}
-}
-
-const ShellUnmountNotifier = GObject.registerClass(
-class ShellUnmountNotifier extends MessageTray.Source {
- constructor() {
- super({
- iconName: 'media-removable',
- });
- this._notification = null;
- Main.messageTray.add(this);
- }
+ _createNotification(title, body) {
+ this._notification?.destroy();
- show(message) {
- let [header, text] = message.split('\n', 2);
+ const source = MessageTray.getSystemSource();
+ this._notification = new MessageTray.Notification(source, title, body);
- if (!this._notification) {
- this._notification = new MessageTray.Notification(this, header, text);
- this._notification.setTransient(true);
- this._notification.setUrgency(MessageTray.Urgency.CRITICAL);
- } else {
- this._notification.update(header, text);
- }
-
- this.showNotification(this._notification);
+ this._notification.setTransient(true);
+ this._notification.iconName = 'media-removable-symbolic';
+ this._notification.connect('destroy', () => delete this._notification);
+ source.showNotification(this._notification);
}
- done(message) {
- if (this._notification) {
- this._notification.destroy();
- this._notification = null;
- }
+ _showUnmountNotificationDone(message) {
+ if (message)
+ this._createNotification(message, null);
+ }
- if (message) {
- let notification = new MessageTray.Notification(this, message, null);
- notification.setTransient(true);
+ _showUnmountNotification(message) {
+ const [title, body] = message.split('\n', 2);
- this.showNotification(notification);
- }
+ if (!this._notification)
+ this._createNotification(title, body);
+ else
+ this._notification.update(title, body);
}
-});
+}
const ShellMountQuestionDialog = GObject.registerClass({
Signals: {'response': {param_types: [GObject.TYPE_INT]}},
_onActivationFailed() {
this._notification?.destroy();
- const source = new MessageTray.Source({
- title: _('Network Manager'),
- iconName: 'network-error-symbolic',
- });
- source.policy =
- new MessageTray.NotificationApplicationPolicy('gnome-network-panel');
-
+ const source = MessageTray.getSystemSource();
this._notification = new MessageTray.Notification(source,
_('Connection failed'),
_('Activation of network connection failed'));
+ this._notification.iconName = 'network-error-symbolic';
this._notification.setUrgency(MessageTray.Urgency.HIGH);
this._notification.setTransient(true);
this._notification.connect('destroy',
Main.sessionMode.connect('updated', this._sync.bind(this));
this._sync();
- this._source = null;
this._perm = null;
this._createPermission();
}
this._client.close();
}
- _ensureSource() {
- if (!this._source) {
- this._source = new MessageTray.Source({
- title: _('Thunderbolt'),
- iconName: 'thunderbolt-symbolic',
- });
- this._source.connect('destroy', () => (this._source = null));
-
- Main.messageTray.add(this._source);
- }
-
- return this._source;
- }
-
_notify(title, body) {
if (this._notification)
this._notification.destroy();
- let source = this._ensureSource();
-
+ const source = MessageTray.getSystemSource();
this._notification = new MessageTray.Notification(source, title, body);
+ this._notification.iconName = 'thunderbolt-symbolic';
this._notification.setUrgency(MessageTray.Urgency.HIGH);
this._notification.connect('destroy', () => {
this._notification = null;
// notification
console.debug('Show notification message');
- const source = new MessageTray.SystemNotificationSource();
- Main.messageTray.add(source);
+ const source = new MessageTray.getSystemSource();
Scripting.scriptEvent('notificationShowStart');
source.connect('notification-show',